package br.unicamp.ic.sgct.client.aplicacao.conferencia;

import java.util.List;


import br.unicamp.ic.sgct.client.SisGesConfTec;
import br.unicamp.ic.sgct.client.aplicacao.comum.BaseListenerImpl;
import br.unicamp.ic.sgct.client.aplicacao.usuario.UsuarioService;
import br.unicamp.ic.sgct.client.aplicacao.usuario.UsuarioServiceAsync;
import br.unicamp.ic.sgct.client.apresentacao.widgets.MensagemUI;
import br.unicamp.ic.sgct.client.dominio.exception.InfraException;
import br.unicamp.ic.sgct.client.dominio.to.AreaTO;
import br.unicamp.ic.sgct.client.dominio.to.ConferenciaTO;
import br.unicamp.ic.sgct.client.dominio.to.ParticipanteTO;
import br.unicamp.ic.sgct.client.dominio.to.UsuarioTO;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;

public class ConferenciaListenerImpl extends BaseListenerImpl implements ConferenciaListener {

    private ConferenciaServiceAsync service;
    private UsuarioServiceAsync service2;

    public ConferenciaListenerImpl(MensagemUI msgWidget) {
        super(msgWidget);
        getService();
    }

    /**
     *
     * @return ConferenciaServiceAsync
     */
    public ConferenciaServiceAsync getService() {
        if (service == null) {
            service = GWT.create(ConferenciaService.class);
            ServiceDefTarget target = (ServiceDefTarget) service;
            target.setServiceEntryPoint(SisGesConfTec.instance().getModuleRelativeURL() + ConferenciaService._RELATIVE_PATH);
        }
        return service;
    }

    /**
     * @return the service2
     */
    public UsuarioServiceAsync getService2() {
        if (service2 == null) {
            service2 = GWT.create(UsuarioService.class);
            ServiceDefTarget target = (ServiceDefTarget) service2;
            target.setServiceEntryPoint(SisGesConfTec.instance().getModuleRelativeURL() + UsuarioService._RELATIVE_PATH);
        }
        return service2;
    }

    /**
     *
     * @return List<ConferenciaTO>
     *
     * @throws InfraException
     * @throws Exception
     */
    @Override
    public void obterConferenciasDisponiveis(final HandlerObterConferenciasDisponiveis handler) {

        getService().obterConferenciasDisponiveis(new AsyncCallback<List<ConferenciaTO>>() {

            @Override
            public void onSuccess(List<ConferenciaTO> result) {
                handler.handleSucesso(result);
            }

            @Override
            public void onFailure(Throwable caught) {
                handler.handleErro(caught);
            }
        });
    }

    /**
     *
     * @return List<ConferenciaTO>
     *
     * @throws InfraException
     * @throws Exception
     */
    @Override
    public void listarConferenciasAbertas(final HandlerListarConferenciasAbertas handler) {

        getService().listarConferenciasAbertas(new AsyncCallback<List<ConferenciaTO>>() {

            @Override
            public void onSuccess(List<ConferenciaTO> result) {
                handler.handleSucesso(result);
            }

            @Override
            public void onFailure(Throwable caught) {
                handler.handleErro(caught);
            }
        });
    }

    /*
    private void setConferencias(List<ConferenciaTO> conferencias) {
    if (this.screen instanceof BaseConferenciaScreen) {
    //((BaseConferenciaScreen) this.screen).setConferencias(conferencias);
    }
    }
     * 
     */
    @Override
    public void obterConferencia(long id, final HandlerObterConferencia handler) {
        getService().obterConferencia(id, new AsyncCallback<ConferenciaTO>() {

            @Override
            public void onSuccess(ConferenciaTO result) {
                handler.handleSucesso(result);
            }

            @Override
            public void onFailure(Throwable caught) {
                handler.handleErro(caught);

            }
        });
    }

    //@Override
    public void obterListaAreasConferencia(long id, final HandlerObterListaAreasConferencia handler) {
        getService().obterListaAreasConferencia(id, new AsyncCallback<List<AreaTO>>() {

            @Override
            public void onSuccess(List<AreaTO> result) {
                handler.handleSucesso(result);
            }

            @Override
            public void onFailure(Throwable caught) {
                handler.handleErro(caught);

            }
        });
    }

    @Override
    public void obterAreasParticipantesParticipanteConferencia(final ConferenciaTO conferencia, final HandlerObterAreasParticipantesParticipanteConferencia handler) {


        getService2().obterParticipantesConferencia(conferencia.getId(), new AsyncCallback<List<ParticipanteTO>>() {

            @Override
            public void onFailure(Throwable caught) {
                handler.handleErro(caught);
            }

            @Override
            public void onSuccess(final List<ParticipanteTO> participantesConferencia) {
                obterAreasParticipantesParticipanteConferencia(conferencia, handler, participantesConferencia);

            }
        });
    }

    private void obterAreasParticipantesParticipanteConferencia(final ConferenciaTO conferencia, final HandlerObterAreasParticipantesParticipanteConferencia handler, final List<ParticipanteTO> participantesConferencia) {
        getService2().obterParticipanteConferencia(conferencia.getId(), new AsyncCallback<ParticipanteTO>() {

            @Override
            public void onFailure(Throwable caught) {
                handler.handleErro(caught);
            }

            @Override
            public void onSuccess(final ParticipanteTO participante) {
                obterAreasParticipantesParticipanteConferencia(conferencia, handler, participantesConferencia, participante);
            }
        });
    }

    private void obterAreasParticipantesParticipanteConferencia(final ConferenciaTO conferencia, final HandlerObterAreasParticipantesParticipanteConferencia handler, final List<ParticipanteTO> participantesConferencia, final ParticipanteTO participante) {
        if (conferencia.getAreas() == null) {
            getService().obterListaAreasConferencia(conferencia.getId(), new AsyncCallback<List<AreaTO>>() {

                @Override
                public void onSuccess(final List<AreaTO> result1) {
                    conferencia.setAreas(result1);
                    handler.handleSucesso(conferencia.getAreas(), participantesConferencia, participante);
                }

                @Override
                public void onFailure(Throwable caught) {
                    handler.handleErro(caught);

                }
            });
        } else {
            handler.handleSucesso(conferencia.getAreas(), participantesConferencia, participante);
        }
    }

    @Override
    public void obterUsuarioParticipacoesAreas(final ConferenciaTO conferencia, final HandlerObterUsuarioParticipacoesAreas handler) {
        getService2().obterParticipacoesConferencia(conferencia.getId(), new AsyncCallback<List<UsuarioTO>>() {

            @Override
            public void onFailure(Throwable caught) {
                handler.handleErro(caught);
            }

            @Override
            public void onSuccess(List<UsuarioTO> participacoesUsuarioConferencia) {
                obterUsuarioParticipacoesAreas(conferencia, handler, participacoesUsuarioConferencia);
            }
        });

    }

    private void obterUsuarioParticipacoesAreas(final ConferenciaTO conferencia, final HandlerObterUsuarioParticipacoesAreas handler, final List<UsuarioTO> participacoesUsuarioConferencia) {
        if (participacoesUsuarioConferencia.isEmpty()) {
            getService2().obterUsuario(new AsyncCallback<UsuarioTO>() {

                @Override
                public void onFailure(Throwable caught) {
                    handler.handleErro(caught);
                }

                @Override
                public void onSuccess(UsuarioTO result) {
                    obterUsuarioParticipacoesAreas(conferencia, handler, participacoesUsuarioConferencia, result);
                }
            });

        } else {
            obterUsuarioParticipacoesAreas(conferencia, handler, participacoesUsuarioConferencia, participacoesUsuarioConferencia.get(0));
        }

    }

    private void obterUsuarioParticipacoesAreas(final ConferenciaTO conferencia, final HandlerObterUsuarioParticipacoesAreas handler, final List<UsuarioTO> participacoesUsuarioConferencia, final UsuarioTO usuario) {
        if (conferencia.getAreas() == null) {
            getService().obterListaAreasConferencia(conferencia.getId(), new AsyncCallback<List<AreaTO>>() {

                @Override
                public void onFailure(Throwable caught) {
                    handler.handleErro(caught);
                }

                @Override
                public void onSuccess(List<AreaTO> result) {
                    conferencia.setAreas(result);
                    obterUsuarioParticipacoesAreas(conferencia, handler, participacoesUsuarioConferencia, usuario, conferencia.getAreas());
                }
            });
        } else {
            obterUsuarioParticipacoesAreas(conferencia, handler, participacoesUsuarioConferencia, usuario, conferencia.getAreas());
        }
    }

    private void obterUsuarioParticipacoesAreas(final ConferenciaTO conferencia, final HandlerObterUsuarioParticipacoesAreas handler, final List<UsuarioTO> participacoesUsuarioConferencia, final UsuarioTO usuario, final List<AreaTO> areas) {
        handler.handleSucesso(areas, participacoesUsuarioConferencia, usuario);
    }
}
